package mars.wizards;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWizard;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;

/**
 * This is a sample new wizard. Its role is to create a new file resource in the
 * provided container. If the container resource (a folder or a project) is
 * selected in the workspace when the wizard is opened, it will accept it as the
 * target container. The wizard creates one file with the extension "mpe". If a
 * sample multi-page editor (also available as a template) is registered for the
 * same extension, it will be able to open it.
 */

public class WidgetNewWizard extends Wizard implements INewWizard {
	private WizardNewProjectCreationPage _mainPage;
	private ISelection selection;
	private IWorkbench _workbench;
	private IProject _newProject;

	/**
	 * Constructor for WidgetNewWizard.
	 */
	public WidgetNewWizard() {
		super();
		setNeedsProgressMonitor(true);
	}

	/**
	 * Adding the page to the wizard.
	 */

	public void addPages() {
		super.addPages();
		_mainPage = new WizardNewProjectCreationPage("Nokia Widgets- Initial");
		_mainPage.setTitle("Create Widget");
		_mainPage.setDescription("Create a new Widget");
		addPage(_mainPage);
	}

	/**
	 * The worker method. It will find the container, create the file if missing
	 * or just replace its contents, and open the editor on the newly created
	 * file.
	 */

	private void doFinish(String containerName, String fileName,
			IProgressMonitor monitor) throws CoreException {
		// create a sample file
		monitor.beginTask("Creating " + fileName, 2);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IResource resource = root.findMember(new Path(containerName));
		if (!resource.exists() || !(resource instanceof IContainer)) {
			throwCoreException("Container \"" + containerName
					+ "\" does not exist.");
		}
		IContainer container = (IContainer) resource;
		final IFile file = container.getFile(new Path(fileName));
		try {
			InputStream stream = openContentStream();
			if (file.exists()) {
				file.setContents(stream, true, true, monitor);
			} else {
				file.create(stream, true, monitor);
			}
			stream.close();
		} catch (IOException e) {
		}
		monitor.worked(1);
		monitor.setTaskName("Opening file for editing...");
		getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				IWorkbenchPage page = PlatformUI.getWorkbench()
						.getActiveWorkbenchWindow().getActivePage();
				try {
					IDE.openEditor(page, file, true);
				} catch (PartInitException e) {
				}
			}
		});
		monitor.worked(1);
	}

	private void throwCoreException(String message) throws CoreException {
		IStatus status = new Status(IStatus.ERROR, "mars", IStatus.OK, message,
				null);
		throw new CoreException(status);
	}

	/**
	 * We will accept the selection in the workbench to see if we can initialize
	 * from it.
	 * 
	 * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
	 */
	public void init(IWorkbench workbench, IStructuredSelection selection) {
		this._workbench = workbench;
		setNeedsProgressMonitor(true);
		setWindowTitle("Create a New Nokia Widget Project");
	}

	/** */
	/**
	 * @see org.eclipse.jface.wizard.Wizard#performFinish()
	 */
	public boolean performFinish() {
		createJavaProject();
		if (_newProject == null) {
			return false;
		} else {
			updatePerspective();
			selectAndReveal(_newProject);
			return true;
		}
	}

	public void createJavaProject() {
		_newProject = createNewProject();

		try {
			createOutputLocation(_newProject);
			_newProject.build(IncrementalProjectBuilder.FULL_BUILD, null);
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	private IProject createNewProject() {
		if (_newProject != null)
			return _newProject;

		
		final IProject newProjectHandle = _mainPage.getProjectHandle();

		IPath newPath = null;
		if (!_mainPage.useDefaults())
			newPath = _mainPage.getLocationPath();

		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		final IProjectDescription description = workspace.newProjectDescription(newProjectHandle.getName());
		description.setLocation(newPath);

		
		addJavaNature(description);

		
		WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
			protected void execute(IProgressMonitor monitor)
					throws CoreException {
				createProject(description, newProjectHandle, monitor);
			}
		};

		try {
			getContainer().run(true, true, op);
		} catch (InterruptedException e) {
			return null;
		} catch (InvocationTargetException e) {
			return null;
		}

		_newProject = newProjectHandle;

		return _newProject;
	}

	/** */
	/**
	 * Add Nature Of Java
	 * 
	 * @param iprojectdescription
	 */
	private void addJavaNature(IProjectDescription iprojectdescription) {
		ArrayList<String> arraylist = new ArrayList<String>();
		arraylist.addAll(Arrays.asList(iprojectdescription.getNatureIds()));
		arraylist.add("org.eclipse.jdt.core.javanature");
		iprojectdescription.setNatureIds(arraylist
				.toArray(new String[arraylist.size()]));
	}

	/**
	 * Create A New Project
	 * 
	 * @param description
	 * @param projectHandle
	 * @param monitor
	 * @throws CoreException
	 * @throws OperationCanceledException
	 */
	private void createProject(IProjectDescription description,
			IProject projectHandle, IProgressMonitor monitor)
			throws CoreException, OperationCanceledException {
		try {

			System.out.println("---------------create project-----------");
			monitor.beginTask("", 2000);

			projectHandle.create(description, new SubProgressMonitor(monitor,
					1000));

			if (monitor.isCanceled())
				throw new OperationCanceledException();

			projectHandle.open(IResource.BACKGROUND_REFRESH,
					new SubProgressMonitor(monitor, 1000));

		} finally {
			monitor.done();
		}
	}

	/**
	 * Create Path
	 * 
	 * @param ijavaproject
	 * @throws JavaModelException
	 * @throws CoreException
	 */
	private void createOutputLocation(IProject iProject) throws CoreException {

		IFolder ifolder = iProject.getProject().getFolder("bin");
		IFolder srcfolder = iProject.getProject().getFolder("src");
		createFolder(ifolder);
		createFolder(srcfolder);
		createWidgetFiles(iProject.getName());
		IPath ipath = ifolder.getFullPath();

	}

	/**
	 * 
	 * 
	 * @param ijavaproject
	 * @throws CoreException
	 */
	private void addJavaBuilder(IProject iProject) throws CoreException {
		IProjectDescription iprojectdescription = iProject.getProject()
				.getDescription();
		ICommand icommand = iprojectdescription.newCommand();
		icommand.setBuilderName("org.eclipse.jdt.core.javabuilder");
		iprojectdescription.setBuildSpec(new ICommand[] { icommand });
		iprojectdescription
				.setNatureIds(new String[] { "org.eclipse.jdt.core.javanature" });
		iProject.getProject().setDescription(iprojectdescription, null);
	}

	
	/**
	 * 
	 * @param ijavaproject
	 * @throws JavaModelException
	 * @throws CoreException
	 */
	// private void setClasspath(IJavaProject ijavaproject)
	// throws JavaModelException, CoreException {
	// ijavaproject.setRawClasspath(new IClasspathEntry[0], null);
	// addSourceFolders(ijavaproject);
	// addJRELibraries(ijavaproject);
	// addCodeGenLibraries(ijavaproject);
	// }
	/** */
	/**
	 * 
	 * @param ijavaproject
	 * @throws JavaModelException
	 */
	// private void addJRELibraries(IJavaProject ijavaproject)
	// throws JavaModelException {
	// ArrayList arraylist = new ArrayList();
	// arraylist.addAll(Arrays.asList(ijavaproject.getRawClasspath()));
	// arraylist.addAll(Arrays.asList(PreferenceConstants
	// .getDefaultJRELibrary()));
	// ijavaproject.setRawClasspath((IClasspathEntry[]) arraylist
	// .toArray(new IClasspathEntry[arraylist.size()]), null);
	// }

	/**
	 * 
	 * @param ijavaproject
	 * @throws JavaModelException
	 */
	// private void addCodeGenLibraries(IJavaProject ijavaproject)
	// throws JavaModelException {
	// // TODO:添加代码生成项目中所需要的Jar包
	// }
	/** */
	/**
	 * 
	 * @param ijavaproject
	 * @throws JavaModelException
	 * @throws CoreException
	 */
	// private void addSourceFolders(IJavaProject ijavaproject)
	// throws JavaModelException, CoreException {
	// ArrayList arraylist = new ArrayList();
	// arraylist.addAll(Arrays.asList(ijavaproject.getRawClasspath()));
	// addSourceFolder(ijavaproject, arraylist, "src/java");
	// addSourceFolder(ijavaproject, arraylist, "src/resource");
	// ijavaproject.setRawClasspath((IClasspathEntry[]) arraylist
	// .toArray(new IClasspathEntry[arraylist.size()]), null);
	// }
	/** */
	/**
	 * 
	 * @param ijavaproject
	 * @param arraylist
	 * @param s
	 * @throws CoreException
	 */
	// private void addSourceFolder(IJavaProject ijavaproject,
	// ArrayList arraylist, String s) throws CoreException {
	// IFolder ifolder = ijavaproject.getProject().getFolder(s);
	// createFolder(ifolder);
	// IPackageFragmentRoot ipackagefragmentroot = ijavaproject
	// .getPackageFragmentRoot(ifolder);
	// arraylist.add(JavaCore.newSourceEntry(ipackagefragmentroot.getPath()));
	// }
	/** */
	/**
	 * 
	 * @param ifolder
	 * @throws CoreException
	 */
	private void createFolder(IFolder ifolder) throws CoreException {
		IContainer icontainer = ifolder.getParent();
		if (icontainer != null && !icontainer.exists()
				&& (icontainer instanceof IFolder))
			createFolder((IFolder) icontainer);
		ifolder.create(true, true, null);
	}

	private InputStream openContentStream() {
		String contents = "initial content";
		return new ByteArrayInputStream(contents.getBytes());
	}

	private InputStream getInfoPlistTemplate(String string) {
		// @todo get the content from template file
		String contents = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
				+ "<!DOCTYPE plist PUBLIC \"-//Nokia//DTD PLIST 1.0//EN\" \"http://www.nokia.com/foo.dtd\">\r\n"
				+ "<plist version=\"1.0\">\r\n" + "<dict>\r\n"
				+ "	<key>DisplayName</key>\r\n" + "	<string>" + string
				+ "</string>\r\n" + "		<key>Identifier</key>\r\n"
				+ "	<string>com.nokia." + string + "</string>\r\n"
				+ "		<key>MainHTML</key>\r\n" + "	<string>" + string
				+ ".html</string>\r\n" + "		<key>AllowNetworkAccess</key>\r\n"
				+ "	<true/>\r\n" + "		<key>Version</key>\r\n"
				+ "	<string>1.0</string>\r\n" + "</dict>\r\n" + "</plist>";
		return new ByteArrayInputStream(contents.getBytes());
	}

	private void createFile(IFile iFile) throws CoreException {
		IContainer icontainer = iFile.getParent();
		if (icontainer != null && !icontainer.exists()
				&& (icontainer instanceof IFolder))
			createFile((IFile) icontainer);
		iFile.create(openContentStream(), true, null);
	}

	private void createWidgetFiles(String widgetName) throws CoreException {
		processInfoPlistFile();
		processIconPngFile();
		processHtml();
		processCss();
		processJavaScript();
	}

	/**
	 */
	protected void updatePerspective() {
		try {
			IWorkbenchPage iworkbenchpage = PlatformUI.getWorkbench()
					.getActiveWorkbenchWindow().getActivePage();
			if (iworkbenchpage.findView("org.eclipse.ui.views.PropertySheet") == null)
				iworkbenchpage.showView("org.eclipse.ui.views.PropertySheet");
		} catch (PartInitException partinitexception) {
			partinitexception.printStackTrace();
		}
	}

	/**
	 * @param iresource
	 */
	protected void selectAndReveal(IResource iresource) {
		selectAndReveal(iresource, _workbench.getActiveWorkbenchWindow());
	}

	/**
	 * 
	 * @param iresource
	 * @param iworkbenchwindow
	 */
	private void selectAndReveal(IResource iresource,
			IWorkbenchWindow iworkbenchwindow) {
		BasicNewResourceWizard.selectAndReveal(iresource, iworkbenchwindow);
	}

	/**
	 */

	@SuppressWarnings("unused")
	private void doFinish(final String fileName, final IProgressMonitor monitor)
			throws CoreException {
		final IFile file = _newProject.getFile(fileName);
		try {
			InputStream stream = openContentStream();
			if (file.exists()) {
				file.setContents(stream, true, true, monitor);
			} else {
				file.create(stream, true, monitor);
			}
			stream.close();
		} catch (IOException e) {
			
		}
		monitor.worked(1);
		monitor.setTaskName("openning file");
		getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				IWorkbenchPage page = PlatformUI.getWorkbench()
						.getActiveWorkbenchWindow().getActivePage();
				try {

					IDE.openEditor(page, file, true);
				} catch (PartInitException e) {
				}
			}
		});
		monitor.worked(1);
	}

	private void processInfoPlistFile() throws CoreException {
		final IFile file = _newProject.getFile("src/Info.plist");
		try {
			InputStream stream = getInfoPlistTemplate(_newProject.getName());
			if (file.exists()) {
				file.setContents(stream, true, true, null);
			} else {
				file.create(stream, true, null);
			}
			stream.close();
		} catch (IOException e) {
		}
	}

	private void processIconPngFile() throws CoreException {
		final IFile file = _newProject.getFile("src/Icon.png");
		try {
			InputStream stream = getInfoPlistTemplate(_newProject.getName());
			if (file.exists()) {
				file.setContents(stream, true, true, null);
			} else {
				file.create(stream, true, null);
			}
			stream.close();
		} catch (IOException e) {
		}
	}
	
	private InputStream openContentStream(String string) {		   
		        return new ByteArrayInputStream(string.getBytes());
		    }

	private void processHtml() throws CoreException {
		final IFile file = _newProject.getFile("src/"+_newProject.getName()+".html");
		try {
			InputStream stream = openContentStream("<html></html>");
			if (file.exists()) {
				file.setContents(stream, true, true, null);
			} else {
				file.create(stream, true, null);
			}
			stream.close();
		} catch (IOException e) {
		}
	}

	private void processCss() throws CoreException {
		final IFile file = _newProject.getFile("src/"+_newProject.getName()+".css");
		try {
			InputStream stream = openContentStream(".css");
			if (file.exists()) {
				file.setContents(stream, true, true, null);
			} else {
				file.create(stream, true, null);
			}
			stream.close();
		} catch (IOException e) {
		}
	}

	private void processJavaScript() throws CoreException {
		final IFile file = _newProject.getFile("src/"+_newProject.getName()+".js");
		try {
			InputStream stream = openContentStream("alert('initial')");
			if (file.exists()) {
				file.setContents(stream, true, true, null);
			} else {
				file.create(stream, true, null);
			}
			stream.close();
		} catch (IOException e) {
		}}

}